'''
This module implements the harvesting of links and fallback metadata from the TvShack.net website 

Created on Jan 24, 2010

@author: pguedes
'''
from utils.pluginsupport import PluginMovieItem
import metadata.metadata as metadatautils
from metadata.metadata import Metadata
import linkresolvers
import utils.htmlutils as http, re, urllib
import xbmc, xbmcgui, xbmcplugin #@UnresolvedImport
import logging

log = logging.getLogger("tvshack")

def listCategories():
  '''
  List the root categories for this plugin
  @return: a list of PluginMovieItems with the root categories
  '''
  yield PluginMovieItem("Tv", 'http://tvshack.net/tv', mode=1), 5
  yield PluginMovieItem("Movies", 'http://tvshack.net/movies', mode=1), 5
  yield PluginMovieItem("Anime", 'http://tvshack.net/anime', mode=1), 5
  yield PluginMovieItem("Music", 'http://tvshack.net/music', mode=1), 5
  yield PluginMovieItem("Documentaries", 'http://tvshack.net/documentaries', mode=1), 5

def RSS(url):
  '''
  Load RSS feed with most recent updates
  @deprecated: this is currently not used, because I don't! 
  '''
  link = http.get(url)
  rss = re.compile('<title>(.+?)</title>\n\t\t<link>(.+?)</link>').findall(link)
  for name, ref in rss:
    mode = 3
    if url.find('movies.xml') > 0:
      mode = 2
    yield PluginMovieItem(name, ref, mode), len(rss)

def doInteractiveSearch():
  '''
  Do an interactive search of TvShack.net's files
  @deprecated: this is currently not used, because I don't! 
  '''
  items=[]
  keyb = xbmc.Keyboard('', 'Search TV Shack')
  keyb.doModal()
  if (keyb.isConfirmed()):
    search = keyb.getText()
    encode = urllib.quote(search)
    html = http.get('http://tvshack.net/search/' + encode, cleanup=True)
    match = re.compile('<li><a href="(.+?)">.+?<strong>(.+?)</strong></a>').findall(html)
    for url, name in match:
      items.append(PluginMovieItem(name, url, _getMode(url)))
  return items
 
def _getMode(url):
  '''
  Get the execution mode for this plugin
  The execution mode is used by the plugin to track the type of url being used
  @param url: the url to get the execution mode for
  '''
  mode = 4
  if url.find('/movies/') >= 0:
    mode = 2
  elif url.find('/documentaries/') >= 0 or url.find('/comedy/') >= 0:
    mode = 3
  return mode
  
def _harvestCoverArt(html):
  '''
  Read the cover from a TVShack tvshow/movie/documentary page
  @param html: the page's html to parse from
  @return: the cover from tvshack or "" if not found
  '''
  thumb = re.compile('<img src="(.+?)" alt="Poster" />').findall(html)
  log.debug("Found thumb: %s" % thumb)
  if len(thumb) == 1:
    return thumb[0]
  return ""

def _harvestSummary(html):
  '''
  Read the summary from a TVShack tvshow/movie/documentary page
  @param html: the page's html to parse from
  @return: the summary from tvshack or "" if not found
  '''
  summary = re.compile('<h3>Summary</h3>.+?<div>(.+?)</div>', re.DOTALL).findall(html)
  log.debug("Found summary: %s" % summary)
  if len(summary) == 1:
    return summary[0]
  return ""

def loadInfo(url, name):
  '''
  Force a refresh of the metadata information for an item.
  @param url: url of the title being refreshed
  @param name: the name of the title being refreshed (used for querying)
  @return: true if the metadata was refreshed with online db data, false otherwise
  '''
  log.info("Loading info for url '%s' of type '%s'"%(url, type))
  keyb = xbmc.Keyboard(name, 'Edit title to search')
  keyb.doModal()
  if (keyb.isConfirmed()):
    search = keyb.getText()
    meta = metadatautils.get(url, queryOnlineDb=True, bypassCache=True, title=search)
  return meta.isImdb()

def listCategory(url, name):
  '''
  List all the TVShows/Movies/... available
  @param url: url of the title being refreshed
  @param name: the name of the title being refreshed (used for querying)
  @return: a list of PluginMovieItems
  '''
  items = []
  page = http.get(url, cleanup=True)
  #log.debug(page)
  match = re.compile('<li><a href="(.+?)">(.+?)<span').findall(page)
  #log.debug("matches=" + str(match))  
  for url, name in match:
    metadata = metadatautils.get(url, title=name)
    yield PluginMovieItem(name, url, _getMode(url), metadata), len(match)
                
def listEpisodes(url, tvshow):
  '''
  List the episodes for a TV Show
  @param url: the tvshack url to load episodes from
  @param tvshow: the tvshow being listed
  @return: a list of PluginMovieItem with the episode items
  '''
  html = http.get(url, cleanup=True)
  fallbackcover = _harvestCoverArt(html)
  fallbackplot = _harvestSummary(html)
  tvshowMetadata = metadatautils.get(url, fallbackplot, fallbackcover, True, title=tvshow, tvshow=True, persistUpdates=False)
  log.info("tvshow details: %s"%str(tvshowMetadata))
  fallbackMetadata = Metadata(tvshow, fallbackplot, fallbackcover).tvshow(tvshow)

  episodeLinks = re.compile('<li><a href="(.+?)">(.+?)</a><a href=""><span>.+?</span></a>').findall(html)
  if len(episodeLinks) < 1:
    episodeLinks = re.compile('<a href="(.+?)">(.+?)<span>').findall(html)
  itemCount = len(episodeLinks)
  for url, episode in episodeLinks:
    try:
      episodeMetadata = metadatautils.get(url, fallbackplot, fallbackcover, True, title=episode, tvshow=tvshowMetadata, persistUpdates=False)
      log.debug("Episode meta: %s"%str(episodeMetadata))
      title = episodeMetadata.getSeasonedTitle()
      yield PluginMovieItem(title, url, 2, episodeMetadata), itemCount
      log.debug("Added item with title: %s"%title)
    except:
      log.exception("Failed to load episode data")
      fallbackMetadata.title(episode)
      yield PluginMovieItem(episode, url, 2, fallbackMetadata), itemCount 
  metadatautils.flushCache(url)
                  
def resolveFiles(url, name, forceSourceSelection=False):
  '''
  Resolve the files for a movie/episode/... item

  Resolving a file is split into three phases:
  1-Select file source (megavideo, veoh, tudou, youku, ...)
  2-Load parts (if item is split for the selected source)
  3-Resolve file links for the parts from the previous step
  
  If an item has only one available source, then that source is auto-selected, otherwise
  the user is shown a XBMC dialog to select the source. If the 'autoplay-preferred-source'
  setting is enabled, the first available source that matches the 'preferred-source' setting
  will be auto-selected.
  
  @param url: the url to resolve files for
  @param name: the name of the playable item being resolved
  @param forceSourceSelection: if the user should be forced to select the source (default False)
  @return: a list of urls of the files to play
  '''
  log.debug("Listing sources: %s" % url)
  html = http.get(url, cleanup=True)
  alt = re.compile('<h3>Alternate links</h3>.(.+?)</ul>', re.DOTALL).findall(html)
  alternateLinks = re.compile('<li><a href="(.+?)"><img src=".+?logos\/(.+?)\.gif" />').findall(str(alt))
  # check if the source has only one part and if so show popup...
  sources = []
  urls = []
  for url, source in alternateLinks:
    if xbmcplugin.getSetting("filter-unsupported-sources") == "true" and not linkresolvers.isSupported(source):
      continue
    sources.append(source)
    urls.append(url)
        
  selected = -1       
  if len(sources) < 2:
    selected = 0
  else:
    if xbmcplugin.getSetting("autoplay-preferred-source") == "true" and not forceSourceSelection:
      autoselect = xbmcplugin.getSetting("preferred-source")
      for index in range(len(sources)):
        if sources[index] == autoselect:
          selected = index
          break
        
    if selected < 0: 
      dialog = xbmcgui.Dialog()
      selected = dialog.select('Select source', sources)
                
  if selected >= 0:
    from linkresolvers import Source
    metadata = metadatautils.get(urls[selected], title=name)
    source = Source(urls[selected], sources[selected], metadata)
    return source.resolve()
